﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace exsportance.Silverlight.Common.Utils
{
    public static class ControlUtils
    {
        private static EventHandler<ExceptionRoutedEventArgs> _imageFailedHandler;

        static ControlUtils()
        {
            _imageFailedHandler = (s, e) =>
                {
                    DebugUtils.WriteLine("Error loading image. " + e.ErrorException.Message);
                };
        }

        /// <summary>
        /// Loads a image from a relative url
        /// </summary>
        /// <param name="imageControl"></param>
        public static void LoadFromUrl(this Image imageControl, string relativeUrl)
        {
            //WebClient downloader = new WebClient();
            //downloader.OpenReadCompleted += new OpenReadCompletedEventHandler((s, e) =>
            //{
            //    // Create a new BitmapImage and load the stream 
            //    BitmapImage loadedImage = new BitmapImage();
            //    loadedImage.SetSource(e.Result);

            //    //  Setting our BitmapImage as the source of a imageControl control I have in XAML 
            //    imageControl.Source = loadedImage;

            //});
            //downloader.OpenReadAsync(relativeUrl.ToUri());

            // remove failed handler if already binded
            imageControl.ImageFailed -= _imageFailedHandler;

            // bind failed handler
            imageControl.ImageFailed += _imageFailedHandler;
            imageControl.Source = new BitmapImage(relativeUrl.ToUri());

        }

        /// <summary>
        /// Starts a new animation on this element
        /// Example:
        /// 
        ///  var a = new DoubleAnimation();
        ///  a.To = 200;
        ///    button.BeginAnimation(Canvas.LeftProperty, a);
        ///</summary>
        /// <param name="obj"></param>
        /// <param name="property"></param>
        /// <param name="animation"></param>
        public static void BeginAnimation(this FrameworkElement obj, DependencyProperty property, DoubleAnimation animation)
        {
            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(animation);
            Storyboard.SetTarget(storyboard, obj);
            Storyboard.SetTargetProperty(storyboard, new PropertyPath(property));
            storyboard.Begin();
        }

        public enum Corner
        {
            LeftTop,
            LeftBottom,
            RightTop,
            RightBottom
        }

        /// <summary>
        /// Get the absolute top left postion
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static Point GetAbsolutePosition(this FrameworkElement element)
        {
            return GetAbsolutePosition(element, Corner.LeftTop);
        }

        /// <summary>
        /// Get the absolute position
        /// </summary>
        /// <param name="element"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public static Point GetAbsolutePosition(this FrameworkElement element, Corner p)
        {
            return GetRelativePosition(element, Application.Current.RootVisual as FrameworkElement, p);
        }

        /// <summary>
        /// Get the relative top left positon to a control
        /// </summary>
        /// <param name="element"></param>
        /// <param name="relativeTo"></param>
        /// <returns></returns>
        public static Point GetRelativePosition(this FrameworkElement element, FrameworkElement relativeTo)
        {
            return GetRelativePosition(element, relativeTo, Corner.LeftTop);
        }

        /// <summary>
        /// Get the relative positon to a control
        /// </summary>
        /// <param name="element"></param>
        /// <param name="relativeTo"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public static Point GetRelativePosition(this FrameworkElement element, FrameworkElement relativeTo, Corner p)
        {
            GeneralTransform gt = element.TransformToVisual(relativeTo);
            Point po = new Point();
            if (p == Corner.LeftTop)
                po = gt.Transform(new Point(0, 0));
            if (p == Corner.LeftBottom)
                po = gt.Transform(new Point(0, element.ActualHeight));
            if (p == Corner.RightTop)
                po = gt.Transform(new Point(element.ActualWidth, 0));
            if (p == Corner.RightBottom)
                po = gt.Transform(new Point(element.ActualWidth, element.ActualHeight));
            return po;
        }
    }
}
